#include <Parser.h>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <llvmir.h>
namespace PARSER
{

    // SymbolTable 实现
    void SymbolTable::add_symbol(const std::string &name, int value, SymbolType type,bool is_globle)
    {
        Symbol symbol;
        symbol.name = name;
        symbol.value = value;
        symbol.type = type;
        symbol.is_globle = is_globle;
        symbols.push_back(symbol);
    }

    int SymbolTable::get_symbol_value(const std::string &name) const
    {
        for (const auto &symbol : symbols)
        {
            if (symbol.name == name)
            {
                return symbol.value;
            }
        }
        throw std::runtime_error("Symbol not found");
    }

    bool SymbolTable::symbol_exists(const std::string &name) const
    {
        for (const auto &symbol : symbols)
        {
            if (symbol.name == name)
            {
                return true;
            }
        }
        return false;
    }

    // Block 实现
    void Block::add_const_decl(std::shared_ptr<ConstDecl> const_decl)
    {
        ast_nodes.push_back(const_decl);
    }

    void Block::add_var_decl(std::shared_ptr<VarDecl> var_decl)
    {
        ast_nodes.push_back(var_decl);
    }

    void Block::add_proc_decl(std::shared_ptr<ProcDecl> proc_decl)
    {
        ast_nodes.push_back(proc_decl);
    }

    void Block::add_statement(std::shared_ptr<Statement> statement)
    {
        ast_nodes.push_back(statement);
    }

    // Parser 实现
    void Parser::update_current_token()
    {
        if (current_token_index < tokens.size())
        {
            current_token = tokens[current_token_index];
            current_token_index++;
        }
        else
        {
            throw std::runtime_error("No more tokens available");
        }
    }

    void Parser::parse_const_decl()
    {
        bool is_globle = false;

        is_globle = level == 0 && !is_begin;
        if (current_token.getType() != LEXER::TokenType::CONSTSYM)
        {
            throw_error("const expected");
        }

        while (true)
        {
            update_current_token();
            if (current_token.getType() != LEXER::TokenType::IDENT)
            {
                throw_error("identifier expected");
            }
            std::string name = current_token.getValue();

            update_current_token();
            bool is_array = false;
            int array_size = 0;
            std::vector<int> array_values;

            // 检查是否为数组声明
            if (current_token.getType() == LEXER::TokenType::LBRACKET) // '['
            {
                is_array = true;
                // 解析数组大小
                update_current_token();
                if (current_token.getType() == LEXER::TokenType::NUMBER)
                {
                    array_size = std::stoi(current_token.getValue());
                    update_current_token();
                    if (current_token.getType() != LEXER::TokenType::RBRACKET) // ']'
                    {
                        throw_error("']' expected after array size");
                    }
                    update_current_token();
                }
                else if (current_token.getType() == LEXER::TokenType::RBRACKET) // ']'
                {
                    // 未指定大小，默认大小为 1
                    array_size = 1;
                    update_current_token();
                }
                else
                {
                    throw_error("number or ']' expected inside '[' ']'");
                }
            }

            // 检查是否有 '='
            bool has_initializer = false;
            if (current_token.getType() == LEXER::TokenType::EQL)
            {
                has_initializer = true;
                update_current_token();
            }

            if (is_array)
            {
                // 数组处理
                if (has_initializer)
                {
                    if (current_token.getType() == LEXER::TokenType::LBRACE) // '{'
                    {
                        // 解析数组初始化列表
                        update_current_token();
                        while (true)
                        {
                            if (current_token.getType() != LEXER::TokenType::NUMBER)
                            {
                                throw_error("number expected in array initialization");
                            }
                            int value = std::stoi(current_token.getValue());
                            array_values.push_back(value);

                            update_current_token();
                            if (current_token.getType() == LEXER::TokenType::COMMA)
                            {
                                update_current_token();
                                continue;
                            }
                            else if (current_token.getType() == LEXER::TokenType::RBRACE) // '}'
                            {
                                update_current_token();
                                break;
                            }
                            else
                            {
                                throw_error("',' or '}' expected in array initialization");
                            }
                        }
                    }
                    else
                    {
                        throw_error("'{' expected for array initialization");
                    }
                }

                // 如果未指定数组大小，且未提供初始化列表，则默认大小为 1
                if (array_size == 0)
                {
                    array_size = array_values.size() > 0 ? array_values.size() : 1;
                }

                // 如果初始化列表的元素数量小于数组大小，填充剩余部分为 0
                while (array_values.size() < static_cast<size_t>(array_size))
                {
                    array_values.push_back(0);
                }

                // 创建 ConstDecl 对象
                std::shared_ptr<ConstDecl> const_decl = std::make_shared<ConstDecl>(name, 0, is_globle);
                const_decl->is_array = true;
                const_decl->set_size(array_size);
                const_decl->array_values = array_values;
                const_decl->set_variable_type(VariableType::INT32); // 默认 INT32，或根据需要修改
                const_decl->set_line_num(current_token.get_line_num());
                const_decl->set_column_num(current_token.get_col_num());

                current_block->add_const_decl(const_decl);
                current_block->add_symbol(name, 0, SymbolType::CONST_ARRAY,is_globle);
            }
            else
            {
                // 标量处理
                int value = 0; // 默认值为 0
                if (has_initializer)
                {
                    if (current_token.getType() != LEXER::TokenType::NUMBER)
                    {
                        throw_error("number expected in const statement");
                    }
                    value = std::stoi(current_token.getValue());
                    update_current_token();
                }

                std::shared_ptr<ConstDecl> const_decl = std::make_shared<ConstDecl>(name, value, is_globle);
                const_decl->set_line_num(current_token.get_line_num());
                const_decl->set_column_num(current_token.get_col_num());
                const_decl->set_variable_type(VariableType::INT32); // 默认 INT32，或根据需要修改
                const_decl->is_array = false;

                current_block->add_const_decl(const_decl);
                current_block->add_symbol(name, value, SymbolType::CONST, is_globle);
            }

            // 检查是否有逗号或分号
            if (current_token.getType() == LEXER::TokenType::SEMICOLON)
            {
                break;
            }
            else if (current_token.getType() == LEXER::TokenType::COMMA)
            {
                continue;
            }
            else
            {
                throw_error("comma or semicolon expected in const statement");
            }
        }
    }

    void Parser::parse_var_decl()
    {
        bool is_globle = false;
        is_globle = level == 0 && !is_begin;
        if (current_token.getType() != LEXER::TokenType::VARSYM)
        {
            throw_error("var expected");
        }

        while (true)
        {
            update_current_token();
            if (current_token.getType() != LEXER::TokenType::IDENT)
            {
                throw_error("identifier expected");
            }
            std::string name = current_token.getValue();

            update_current_token();
            bool is_array = false;
            int array_size = 0;
            std::vector<int> array_values;

            // 检查是否为数组声明
            if (current_token.getType() == LEXER::TokenType::LBRACKET) // '['
            {
                is_array = true;
                // 解析数组大小
                update_current_token();
                if (current_token.getType() == LEXER::TokenType::NUMBER)
                {
                    array_size = std::stoi(current_token.getValue());
                    update_current_token();
                    if (current_token.getType() != LEXER::TokenType::RBRACKET) // ']'
                    {
                        throw_error("']' expected after array size");
                    }
                    update_current_token();
                }
                else if (current_token.getType() == LEXER::TokenType::RBRACKET) // ']'
                {
                    // 未指定大小，默认大小为 1
                    array_size = 1;
                    update_current_token();
                }
                else
                {
                    throw_error("number or ']' expected inside '[' ']'");
                }
            }

            // 检查是否有 '='
            bool has_initializer = false;
            if (current_token.getType() == LEXER::TokenType::EQL)
            {
                has_initializer = true;
                update_current_token();
            }

            if (is_array)
            {
                // 数组处理
                if (has_initializer)
                {
                    if (current_token.getType() == LEXER::TokenType::LBRACE) // '{'
                    {
                        // 解析数组初始化列表
                        update_current_token();
                        while (true)
                        {
                            if (current_token.getType() != LEXER::TokenType::NUMBER)
                            {
                                throw_error("number expected in array initialization");
                            }
                            int value = std::stoi(current_token.getValue());
                            array_values.push_back(value);

                            update_current_token();
                            if (current_token.getType() == LEXER::TokenType::COMMA)
                            {
                                update_current_token();
                                continue;
                            }
                            else if (current_token.getType() == LEXER::TokenType::RBRACE) // '}'
                            {
                                update_current_token();
                                break;
                            }
                            else
                            {
                                throw_error("',' or '}' expected in array initialization");
                            }
                        }
                    }
                    else
                    {
                        throw_error("'{' expected for array initialization");
                    }
                }

                // 如果未指定数组大小，且未提供初始化列表，则默认大小为 1
                if (array_size == 0)
                {
                    array_size = array_values.size() > 0 ? array_values.size() : 1;
                }

                // 如果初始化列表的元素数量小于数组大小，填充剩余部分为 0
                while (array_values.size() < static_cast<size_t>(array_size))
                {
                    array_values.push_back(0);
                }

                // 创建 VarDecl 对象
                std::shared_ptr<VarDecl> var_decl = std::make_shared<VarDecl>(name, is_globle);
                var_decl->is_array = true;
                var_decl->set_size(array_size);
                var_decl->array_values = array_values;
                var_decl->set_variable_type(VariableType::INT32); // 默认 INT32，或根据需要修改
                var_decl->set_line_num(current_token.get_line_num());
                var_decl->set_column_num(current_token.get_col_num());

                current_block->add_var_decl(var_decl);
                current_block->add_symbol(name, 0, SymbolType::VAR_ARRAY,is_globle);
            }
            else
            {
                // 标量处理
                int value = 0; // 默认值为 0
                if (has_initializer)
                {
                    if (current_token.getType() != LEXER::TokenType::NUMBER)
                    {
                        throw_error("number expected in var statement");
                    }
                    value = std::stoi(current_token.getValue());
                    update_current_token();
                }

                std::shared_ptr<VarDecl> var_decl = std::make_shared<VarDecl>(name, is_globle);
                var_decl->value = value;
                var_decl->set_line_num(current_token.get_line_num());
                var_decl->set_column_num(current_token.get_col_num());
                var_decl->set_variable_type(VariableType::INT32); // 默认 INT32，或根据需要修改
                var_decl->is_array = false;

                current_block->add_var_decl(var_decl);
                current_block->add_symbol(name, value, SymbolType::VAR,is_globle);
            }

            // 检查是否有逗号或分号
            if (current_token.getType() == LEXER::TokenType::SEMICOLON)
            {
                break;
            }
            else if (current_token.getType() == LEXER::TokenType::COMMA)
            {
                continue;
            }
            else
            {
                throw_error("comma or semicolon expected in var statement");
            }
        }
    }

    void Parser::parse_proc_decl()
    {
        if (current_token.getType() != LEXER::TokenType::PROCSYM)
        {
            throw std::runtime_error("procedure expected");
        }

        update_current_token();
        if (current_token.getType() != LEXER::TokenType::IDENT)
        {
            throw std::runtime_error("identifier expected");
        }
        std::string name = current_token.getValue();
        last_procedure_name = name;
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::SEMICOLON)
        {
            throw std::runtime_error("semicolon expected");
        }

        std::shared_ptr<ProcDecl> proc_decl = std::make_shared<ProcDecl>(name);
        proc_decl->set_line_num(current_token.get_line_num());
        proc_decl->set_column_num(current_token.get_col_num());
        current_block->add_proc_decl(proc_decl);
        current_block->add_symbol(name, -1, SymbolType::PROC, false);
    }

    std::shared_ptr<Program> program = std::make_shared<Program>();

    std::shared_ptr<Program> Parser::parse_program()
    {
        update_current_token();
        current_block = std::make_shared<Block>();
        current_block->set_symbol_table(std::make_shared<SymbolTable>());
        program->boot_block->set_name("boot");
        current_block->set_name("boot");
        while (!is_token_end())
        {
            std::cout << current_token_index << std::endl;
            update_current_token();
            parse_block();
        }
        program->boot_block = current_block;
        return program;
    }

    void Parser::parse_block()
    {
        if (current_token.getType() == LEXER::TokenType::CONSTSYM)
        {
            parse_const_decl();
        }
        if (current_token.getType() == LEXER::TokenType::VARSYM)
        {
            parse_var_decl();
        }
        if (current_token.getType() == LEXER::TokenType::PROCSYM)
        {
            this->is_in_procedure = true;
            parse_proc_decl();
            update_Block_to_Child();
            current_block->set_name("procedure_" + last_procedure_name);
            level++;
        }
        if (current_token.getType() == LEXER::TokenType::BEGINSYM)
        {
            is_begin = true;
            if (is_begin && level == 0)
            {
                update_Block_to_Child();
                current_block->set_name("main");
            }
        }
        if (current_token.getType() == LEXER::TokenType::ENDSYM)
        {
            is_begin = false;
            update_current_token();
            if (level != 0)
            {
                update_Block_to_parent();
            }
            if (is_in_procedure)
            {
                is_in_procedure = false;
                if (current_token.getType() != LEXER::TokenType::SEMICOLON)
                {
                    throw std::runtime_error("Error: semicolon expected procedure end");
                    exit(1);
                }
            }
            if (is_in_while)
            {
                is_in_while = false;
                if (current_token.getType() != LEXER::TokenType::SEMICOLON)
                {
                    throw std::runtime_error("Error: semicolon expected while end");
                    exit(1);
                }
            }
            if (level != 0)
            {
                level--;
            }
            if (is_in_procedure)
            {
                is_in_procedure = false;
            }
        }

        parse_statement();
    }

    void Parser::parse_statement()
    {
        if (current_token.getType() == LEXER::TokenType::CALLSYM)
        {
            parse_call();
        }
        if (current_token.getType() == LEXER::TokenType::WHILESYM)
        {
            parse_while();
        }
        if (current_token.getType() == LEXER::TokenType::WRITESYM)
        {
            parse_write();
        }
        if (current_token.getType() == LEXER::TokenType::READSYM)
        {
            parse_read();
        }
        if (current_token.getType() == LEXER::TokenType::IFSYM)
        {
            parse_if();
        }
        if (current_token.getType() == LEXER::TokenType::IDENT && get_next_token_type() == LEXER::TokenType::BECOMES)
        {
            parse_assign();
        }
        // 在此处添加对不同类型语句的解析逻辑
        // 例如 parse_assign, parse_call, parse_while, parse_if 等
    }

    void Parser::parse_assign()
    {
        if (current_token.getType() != LEXER::TokenType::IDENT)
        {
            throw_error("identifier expected");
        }
        std::string name = current_token.getValue();

        std::shared_ptr<Symbol> symbol = get_symbol_in_current_and_parent(name);
        if (symbol == NULL || symbol->type != SymbolType::VAR)
        {
            throw_error("Error: variable not found in assignment statement");
        }

        update_current_token();
        if (current_token.getType() != LEXER::TokenType::BECOMES)
        {
            throw_error("equal sign expected");
        }

        update_current_token();
        bool is_while = false;
        bool is_if = false;
        std::shared_ptr<Expression> expression = parse_expression(is_while, is_if);
        std::shared_ptr<Assign> assign = std::make_shared<Assign>(symbol, expression);
        assign->set_line_num(current_token.get_line_num());
        assign->set_column_num(current_token.get_col_num());
        current_block->add_statement(assign);
    }

    bool SymbolTable::name_is_in_symbol_table(const std::string &name)
    {
        for (const auto &symbol : symbols)
        {
            if (symbol.name == name)
            {
                return true;
            }
        }
        return false;
    }

    bool Parser::is_token_end()
    {
        if (current_token.getType() == LEXER::TokenType::PROGRAM_END)
        {
            return true;
        }
        if (current_token.getType() == LEXER::TokenType::PERIOD)
        {
            return true;
        }
        return current_token_index >= tokens.size();
    }

    LEXER::TokenType Parser::get_next_token_type()
    {
        if (current_token_index < tokens.size())
        {
            return tokens[current_token_index].getType();
        }
        return LEXER::TokenType::UNKNOWN;
    }

    void Parser::update_Block_to_Child()
    {
        if (level == 0)
        {
            program->boot_block->merge_with_block(current_block);
            program->boot_block->print_AstNode();
            current_block = std::make_shared<Block>();
            program->boot_block->add_child(current_block);
            current_block->set_parent(program->boot_block);
            current_block->set_symbol_table(std::make_shared<SymbolTable>());
        }
        else
        {
            std::shared_ptr<Block> child_block = std::make_shared<Block>();
            current_block->add_child(child_block);
            child_block->set_parent(current_block);
            child_block->set_symbol_table(std::make_shared<SymbolTable>());
            current_block = child_block;
        }
    }

    void Parser::update_Block_to_parent()
    {
        if (level == 0)
        {
            return;
        }
        if (level != 0)
        {
            if (current_block->get_parent() == nullptr)
            {
                std::cerr << "Error: No parent block found for the current block." << std::endl;
                throw std::runtime_error("Parent block is required but not found.");
            }
            else
            {
                current_block = current_block->get_parent();
            }
        }
    }

    void SymbolTable::merge_with_symbol_table(const std::shared_ptr<SymbolTable> &other)
    {
        for (const auto &symbol : other->symbols)
        {
            this->symbols.push_back(symbol);
        }
    }

    void Block::merge_with_block(const std::shared_ptr<Block> &other)
    {
        for (const auto &ast_node : other->ast_nodes)
        {
            if (std::find(this->ast_nodes.begin(), this->ast_nodes.end(), ast_node) == this->ast_nodes.end())
            {
                this->ast_nodes.push_back(ast_node);
            }
        }
        this->symbol_table->merge_with_symbol_table(other->symbol_table);
    }

    void Parser::parse_call()
    {
        if (current_token.getType() != LEXER::TokenType::CALLSYM)
        {
            throw std::runtime_error("call expected");
        }

        update_current_token();
        if (current_token.getType() != LEXER::TokenType::IDENT)
        {
            throw std::runtime_error("identifier expected");
        }
        std::string name = current_token.getValue();

        std::shared_ptr<Symbol> symbol = get_symbol_in_current_and_parent(name);
        if (symbol == NULL || symbol->type != SymbolType::PROC)
        {
            throw_error("Error: procedure not found in call statement");
        }

        update_current_token();
        if (current_token.getType() != LEXER::TokenType::SEMICOLON)
        {
            throw_error("semicolon expected");
        }
        std::shared_ptr<Call> call = std::make_shared<Call>(name);
        call->set_line_num(current_token.get_line_num());
        call->set_column_num(current_token.get_col_num());
        current_block->add_statement(call);
    }

    std::shared_ptr<Expression> Parser::parse_expression(bool is_while, bool is_if)
    {
        std::shared_ptr<Expression> expression = std::make_shared<Expression>();

        // 假设表达式由一个或多个标识符、数字和运算符组成
        while (current_token.getType() == LEXER::TokenType::IDENT ||
               current_token.getType() == LEXER::TokenType::NUMBER ||
               current_token.getType() == LEXER::TokenType::PLUS ||
               current_token.getType() == LEXER::TokenType::MINUS ||
               current_token.getType() == LEXER::TokenType::TIMES ||
               current_token.getType() == LEXER::TokenType::SLASH ||
               current_token.getType() == LEXER::TokenType::LPAREN ||
               current_token.getType() == LEXER::TokenType::RPAREN ||
               current_token.getType() == LEXER::TokenType::EQL ||
               current_token.getType() == LEXER::TokenType::NEQ ||
               current_token.getType() == LEXER::TokenType::LSS ||
               current_token.getType() == LEXER::TokenType::LEQ ||
               current_token.getType() == LEXER::TokenType::GTR ||
               current_token.getType() == LEXER::TokenType::GEQ)
        {
            expression->express += current_token.getValue();
            update_current_token();
        }
        if (current_token.getType() == LEXER::TokenType::SEMICOLON || (is_while && current_token.getType() == LEXER::TokenType::DOSYM) || (is_if && current_token.getType() == LEXER::TokenType::THENSYM))
        {
            return expression;
        }
        else
        {
            std::cerr << "Error: expression error in parse_expression" << std::endl;
        }
    }

    std::shared_ptr<Block> Block::get_parent()
    {
        return parent;
    }

    void Parser::set_current_block_to_parent()
    {
        if (current_block->get_parent() == nullptr)
        {
            std::cerr << "Error: No parent block found for the current block." << std::endl;
            throw std::runtime_error("Parent block is required but not found.");
        }
        else
        {
            current_block = current_block->get_parent();
        }
    }

    void Parser::parse_while()
    {
        level++;
        is_in_while = true;
        update_Block_to_Child();
        current_block->set_name(get_while_name());
        if (current_token.getType() != LEXER::TokenType::WHILESYM)
        {
            throw std::runtime_error("while expected");
        }
        update_current_token();
        bool is_while = true;
        bool is_if = false;
        std::shared_ptr<Expression> condition = parse_expression(is_while, is_if);
        std::shared_ptr<While> while_statement = std::make_shared<While>(condition);
        while_statement->set_line_num(current_token.get_line_num());
        while_statement->set_column_num(current_token.get_col_num());
        current_block->add_statement(while_statement);
    }

    std::shared_ptr<Symbol> Parser::get_symbol_in_current_and_parent(const std::string &name) const
    {
        std::shared_ptr<Block> block = current_block;
        std::shared_ptr<Symbol> symbol = block->symbol_table->get_symbol_by_name(name);
        while (symbol == nullptr && block->get_parent() != nullptr)
        {
            block = block->get_parent();
            symbol = block->symbol_table->get_symbol_by_name(name);
        }
        return symbol;
    }

    std::shared_ptr<Symbol> SymbolTable::get_symbol_by_name(std::string name) const
    {
        for (const auto &symbol : symbols)
        {
            if (symbol.name == name)
            {
                return std::make_shared<Symbol>(symbol);
            }
        }
        return nullptr;
    }

    void Parser::throw_error(const std::string &msg)
    {
        std::cerr << "Error: " << msg << std::endl;
        std::cerr << "Current token: " << current_token.getValue() << std::endl;
        std::cerr << "Current token type: " << current_token.getType() << std::endl;
        int line_num = current_token.get_line_num();
        int col_num = current_token.get_col_num();
        std::cerr << "Line: " << line_num << ", Column: " << col_num << std::endl;
        exit(1);
    }

    std::string Parser::get_while_name()
    {
        uint num = uint_allocator_for_while.allocate();
        std::string name = "while" + std::to_string(num);
        return name;
    }

    void Parser::parse_write()
    {
        if (current_token.getType() != LEXER::TokenType::WRITESYM)
        {
            throw_error("write expected");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::LPAREN)
        {
            throw_error("left parenthesis expected");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::IDENT)
        {
            throw std::runtime_error("identifier expected");
        }
        std::string name = current_token.getValue();

        std::shared_ptr<Symbol> symbol = get_symbol_in_current_and_parent(name);
        if (symbol == NULL || (symbol->type != VAR && symbol->type != CONST))
        {
            throw_error("Error: variable not found in write statement");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::RPAREN)
        {
            throw_error("right parenthesis expected");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::SEMICOLON)
        {
            throw_error("semicolon expected");
        }
        std::shared_ptr<Write> write = std::make_shared<Write>(symbol);
        write->set_line_num(current_token.get_line_num());
        write->set_column_num(current_token.get_col_num());
        current_block->add_statement(write);
    }

    void Parser::parse_read()
    {
        if (current_token.getType() != LEXER::TokenType::READSYM)
        {
            throw_error("read expected in read statement");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::LPAREN)
        {
            throw_error("left parenthesis expected in read statement");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::IDENT)
        {
            throw std::runtime_error("identifier expected in read statement");
        }
        std::string name = current_token.getValue();

        std::shared_ptr<Symbol> symbol = get_symbol_in_current_and_parent(name);
        if (symbol == NULL || symbol->type != SymbolType::VAR)
        {
            throw_error("Error: variable not found in read statement");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::RPAREN)
        {
            throw_error("right parenthesis expected in read statement");
        }
        update_current_token();
        if (current_token.getType() != LEXER::TokenType::SEMICOLON)
        {
            throw_error("semicolon expected in read statement");
        }
        std::shared_ptr<Read> read = std::make_shared<Read>(symbol);
        read->set_line_num(current_token.get_line_num());
        read->set_column_num(current_token.get_col_num());
        current_block->add_statement(read);
    }

    std::string Parser::get_if_name()
    {
        uint num = uint_allocator_for_if.allocate();
        std::string name = "if" + std::to_string(num);
        return name;
    }

    void Parser::parse_if()
    {
        level++;
        update_Block_to_Child();
        current_block->set_name(get_if_name());
        std::string parent_name = current_block->get_name();
        if (current_token.getType() != LEXER::TokenType::IFSYM)
        {
            throw_error("if expected");
        }
        update_current_token();
        bool is_while = false;
        bool is_if = true;
        std::shared_ptr<Expression> condition = parse_expression(is_while, is_if);
        std::shared_ptr<If> if_statement = std::make_shared<If>(condition);
        if_statement->set_line_num(current_token.get_line_num());
        if_statement->set_column_num(current_token.get_col_num());
        if_statement->name = parent_name;
        current_block->add_statement(if_statement);
        update_Block_to_Child();
        current_block->set_name(parent_name + "_true");

        if (current_token.getType() != LEXER::TokenType::THENSYM)
        {
            throw_error("then expected in if statement");
        }
        update_current_token();
        if (current_token.getType() == LEXER::TokenType::BEGINSYM)
        {
            update_current_token();
            while (current_token.getType() != LEXER::TokenType::ENDSYM)
            {
                parse_statement();
                update_current_token();
            }
        }
        else if (current_token.getType() != LEXER::ElSESYM)
        {
            parse_statement();
        }
        update_Block_to_parent();
        update_Block_to_Child();
        current_block->set_name(parent_name + "_false");
        update_current_token();
        if (current_token.getType() == LEXER::ElSESYM)
        {
            update_current_token();
            if (current_token.getType() == LEXER::TokenType::BEGINSYM)
            {
                while (current_token.getType() != LEXER::TokenType::ENDSYM)
                {
                    parse_statement();
                }
            }
            else
            {
                parse_statement();
            }
        }
        update_Block_to_parent();
        update_Block_to_parent();
        level--;
    }

    void Block::print_AstNode() const
    {
        static int print_level = 0;
        for (const auto &ast_node : ast_nodes)
        {
            // ast_node 为空的判断
            if (ast_node == nullptr)
            {
                continue;
            }
            for (int i = 0; i < print_level; ++i)
            {
                std::cout << "    ";
            }
            if (ast_node->AST_get_type() == ASTNode_Type::BLOCK)
            {
                print_level++;
                std::shared_ptr<Block> block = std::dynamic_pointer_cast<Block>(ast_node);
                std::cout << "Block Name: " << block->get_name() << std::endl;
                block->print_AstNode();
                print_level--;
            }
            else
            {
                std::cout << *ast_node << std::endl;
            }
        }
    }

    inline std::ostream &operator<<(std::ostream &os, const AST_Node &node)
    {
        switch (node.AST_get_type())
        {
        case ASTNode_Type::BLOCK:
        {
            const Block *block = dynamic_cast<const Block *>(&node);
            if (block)
            {
                os << *block;
            }
            else
            {
                os << "Error: Unable to cast AST_Node to Block.\n";
            }
            break;
        }
        case ASTNode_Type::STATEMENT:
        {
            const Statement *stmt = dynamic_cast<const Statement *>(&node);
            if (stmt)
            {
                switch (stmt->statment_get_type())
                {
                case CONST_DECL:
                {
                    const ConstDecl *constDecl = dynamic_cast<const ConstDecl *>(stmt);
                    if (constDecl)
                        os << *constDecl;
                    else
                        os << "Error: Unable to cast Statement to ConstDecl.\n";
                    break;
                }
                case VAR_DECL:
                {
                    const VarDecl *varDecl = dynamic_cast<const VarDecl *>(stmt);
                    if (varDecl)
                        os << *varDecl;
                    else
                        os << "Error: Unable to cast Statement to VarDecl.\n";
                    break;
                }
                case PROC_DECL:
                {
                    const ProcDecl *procDecl = dynamic_cast<const ProcDecl *>(stmt);
                    if (procDecl)
                        os << *procDecl;
                    else
                        os << "Error: Unable to cast Statement to ProcDecl.\n";
                    break;
                }
                case ASSIGN_STAT:
                {
                    const Assign *assign = dynamic_cast<const Assign *>(stmt);
                    if (assign)
                        os << *assign;
                    else
                        os << "Error: Unable to cast Statement to Assign.\n";
                    break;
                }
                case CALL_STAT:
                {
                    const Call *call = dynamic_cast<const Call *>(stmt);
                    if (call)
                        os << *call;
                    else
                        os << "Error: Unable to cast Statement to Call.\n";
                    break;
                }
                case WRITE_STAT:
                {
                    const Write *writeStmt = dynamic_cast<const Write *>(stmt);
                    if (writeStmt)
                        os << *writeStmt;
                    else
                        os << "Error: Unable to cast Statement to Write.\n";
                    break;
                }
                case READ_STAT:
                {
                    const Read *readStmt = dynamic_cast<const Read *>(stmt);
                    if (readStmt)
                        os << *readStmt;
                    else
                        os << "Error: Unable to cast Statement to Read.\n";
                    break;
                }
                case WHILE_STAT:
                {
                    const While *whileStmt = dynamic_cast<const While *>(stmt);
                    if (whileStmt)
                        os << *whileStmt;
                    else
                        os << "Error: Unable to cast Statement to While.\n";
                    break;
                }
                case IF_STAT:
                {
                    const If *ifStmt = dynamic_cast<const If *>(stmt);
                    if (ifStmt)
                        os << *ifStmt;
                    else
                        os << "Error: Unable to cast Statement to If.\n";
                    break;
                }
                default:
                    os << "Unknown Statement Type.\n";
                    break;
                }
            }
            else
            {
                os << "Error: Unable to cast AST_Node to Statement.\n";
            }
            break;
        }

        case ASTNode_Type::EXPRESSION:
        {
            const Expression *expr = dynamic_cast<const Expression *>(&node);
            if (expr)
            {
                os << *expr;
            }
            else
            {
                os << "Error: Unable to cast AST_Node to Expression.\n";
            }
            break;
        }
        default:
            os << "Unknown AST_Node_Type.\n";
            break;
        }
        return os;
    }

    void VarDecl::generate_llvmir(int level) const
    {
        std::string name = this->name;
        int value = this->value;
        int size = this->size;
        bool is_globle = level == 0 && this->is_globle;

        std::vector<int> array_values = this->array_values;
        if (size != 0)
        {
            LLVMIR::var_decl_array(name, array_values, level, size, is_globle);
        }
        else
        {
            LLVMIR::var_decl(name, value, level, is_globle);
        }
    }

    void ConstDecl::generate_llvmir(int level) const
    {
        std::string name = this->name;
        int value = this->value;
        int size = this->size;
        bool is_globle = level == 0 && this->is_globle;

        std::vector<int> array_values = this->array_values;
        if (size != 0)
        {
            LLVMIR::const_decl_array(name, array_values, size, is_globle);
        }
        else
        {
            LLVMIR::const_decl(name, value, level, is_globle);
        }
    }

    void If::generate_llvmir()
    {
        std::string condition = this->condition->express;
        std::string lhs;
        std::string rhs;
        // 解析运算符的左右 运算符可以是 +-*/ 也可以是比较运算符
        for (int i = 0; i < condition.size(); i++)
        {
            if (condition[i] == '+' || condition[i] == '-' || condition[i] == '*' || condition[i] == '/' ||
                condition[i] == '==' || condition[i] == '!=' || condition[i] == '<' || condition[i] == '>' ||
                condition[i] == '<=' || condition[i] == '>=')
            {
                lhs = condition.substr(0, i);
                rhs = condition.substr(i + 1, condition.size() - i - 1);
                break;
            }
        }
        LLVMIR::add_icmp(condition, lhs, rhs, this->name);
    }

    void statment_to_llvmir(std::shared_ptr<Statement> statement, int level)
    {
        Statement_Type type = statement->statment_get_type();
        switch (type)
        {
        case CONST_DECL:
        {
            std::shared_ptr<ConstDecl> constDecl = std::dynamic_pointer_cast<ConstDecl>(statement);
            if (constDecl)
            {
                constDecl->generate_llvmir(level);
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to ConstDecl.\n";
            }
            break;
        }
        case VAR_DECL:
        {
            std::shared_ptr<VarDecl> varDecl = std::dynamic_pointer_cast<VarDecl>(statement);
            if (varDecl)
            {
                std::cout << *varDecl;
                varDecl->generate_llvmir(level);
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to VarDecl.\n";
            }
            break;
        }
        case WRITE_STAT:
        {
            std::shared_ptr<Write> writeStmt = std::dynamic_pointer_cast<Write>(statement);
            if (writeStmt)
            {
                std::cout << *writeStmt;
                writeStmt->generate_llvmir();
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to Write.\n";
            }
            break;
        }
        case READ_STAT:
        {
            std::shared_ptr<Read> readStmt = std::dynamic_pointer_cast<Read>(statement);
            if (readStmt)
            {
                std::cout << *readStmt;
                readStmt->generate_llvmir();
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to Read.\n";
            }
            break;
        }
        case CALL_STAT:
        {
            std::shared_ptr<Call> call = std::dynamic_pointer_cast<Call>(statement);
            if (call)
            {
                std::cout << *call;
                call->generate_llvmir();
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to Call.\n";
            }
            break;
        }
        case PROC_DECL:
        {
        }
        case IF_STAT:
        {
            std::shared_ptr<If> ifStmt = std::dynamic_pointer_cast<If>(statement);
            if (ifStmt)
            {
                std::cout << *ifStmt;
                ifStmt->generate_llvmir();
            }
            else
            {
                std::cout << "Error: Unable to cast Statement to If.\n";
            }
            break;
        }
        }
    }

    void Write::generate_llvmir() const
    {
        std::string name = this->ident->name;
        bool is_global = this->ident->is_globle;
        LLVMIR::write(name,is_global);
    }

    void Read::generate_llvmir() const
    {
        std::string name = this->ident->name;
        LLVMIR::read(name);
    }

    void Call::generate_llvmir() const
    {
        std::string name = this->proc_name;
        LLVMIR::call(name);
    }

    void ProcDecl::generate_llvmir() const
    {
        std::string name = this->name;
        LLVMIR::define_function(name);
    }

    void Parser::generate_llvmir(std::shared_ptr<Block> block, int level) const
    {
        for (const auto &ast_node : block->ast_nodes)
        {
            if (ast_node->AST_get_type() == ASTNode_Type::BLOCK)
            {
                std::shared_ptr<Block> child_block = std::dynamic_pointer_cast<Block>(ast_node);
                if (child_block->get_name() == "main")
                {
                    LLVMIR::define_main_function();
                    LLVMIR::add_left_brace();
                    generate_llvmir(child_block, level + 1);
                    LLVMIR::add_return_void();
                    LLVMIR::add_right_brace();
                }
                else if (child_block->get_name().find("procedure") != std::string::npos)
                {
                    LLVMIR::define_function(child_block->get_name());
                    LLVMIR::add_left_brace();
                    generate_llvmir(child_block, level + 1);
                    LLVMIR::add_return_void();
                    LLVMIR::add_right_brace();
                } else if (child_block->get_name().find("if") != std::string::npos && child_block->get_name().find("true") != std::string::npos)
                {
                    LLVMIR::add_if_true(child_block->get_name());
                    generate_llvmir(child_block, level + 1);
                    std::string lable = child_block->get_name();
                    if (lable.find("_true") != std::string::npos || lable.find("_false") != std::string::npos) {
                        lable = lable.substr(0, lable.find_last_of('_'));
                    }
                    LLVMIR::br(lable+"_end");
                } else if(child_block->get_name().find("if") != std::string::npos && child_block->get_name().find("false") != std::string::npos)
                {
                    LLVMIR::add_if_false(child_block->get_name());
                    generate_llvmir(child_block, level + 1);
                      std::string lable = child_block->get_name();
                    if (lable.find("_true") != std::string::npos || lable.find("_false") != std::string::npos) {
                        lable = lable.substr(0, lable.find_last_of('_'));
                    }
                    LLVMIR::br(lable+"_end");
                    LLVMIR::add_llvm_code(lable+"_end:");
                }else if(child_block->get_name().find("if") != std::string::npos && child_block->get_name().find("true") == std::string::npos
                 && child_block->get_name().find("false") == std::string::npos)
                {
                    generate_llvmir(child_block, level + 1);
                }
            }
            else
            {
                std::shared_ptr<Statement> statement = std::dynamic_pointer_cast<Statement>(ast_node);
                statment_to_llvmir(statement, level);
            }
        }
    }

    void Block::add_ast_node(std::shared_ptr<AST_Node> ast_node)
    {
        ast_nodes.push_back(ast_node);
    }

    std::shared_ptr<Block> Parser::adjust_boot_block(std::shared_ptr<Block> block)
    {
        // std::shared_ptr<Block> boot = std::make_shared<Block>();
        // std::shared_ptr<Block> main = std::make_shared<Block>();
        // for (auto s : block->ast_nodes)
        // {
        //     ASTNode_Type astnoe_type = s->AST_get_type();
        //     if (astnoe_type == ASTNode_Type::BLOCK)
        //     {
        //         main->add_ast_node(s);
        //     }
        //     else
        //     {
        //         // s传承statement
        //         std::shared_ptr<Statement> statement = std::dynamic_pointer_cast<Statement>(s);
        //         Statement_Type statement_type = statement->statment_get_type();
        //         if (statement_type == Statement_Type::CONST_DECL)
        //         {
        //             // s转成CONST_DECL
        //             std::shared_ptr<ConstDecl> constDecl = std::dynamic_pointer_cast<ConstDecl>(s);
        //             bool is_global = constDecl->is_globle;
        //             if (is_global)
        //             {
        //                 boot->add_ast_node(s);
        //             }
        //             else
        //             {
        //                 main->add_ast_node(s);
        //             }
        //         }
        //         else if (statement_type == Statement_Type::VAR_DECL)
        //         {
        //             // s转成VAR_DECL
        //             std::shared_ptr<VarDecl> varDecl = std::dynamic_pointer_cast<VarDecl>(s);
        //             bool is_global = varDecl->is_globle;
        //             if (is_global)
        //             {
        //                 boot->add_ast_node(s);
        //             }
        //             else
        //             {
        //                 main->add_ast_node(s);
        //             }
        //         }else
        //         {
        //             main->add_ast_node(s);
        //         }
        //     }
        // }
        // boot->add_child(main);
        // main->set_parent(boot);
        // boot->set_name("boot");
        // main->set_name("main");
        // return boot;

        while (block->get_parent() != nullptr)
        {
            block = block->get_parent();
        }
        return block;
    }

} // namespace PARSER
